package br.ucb.tcc.utils;

import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

import org.apache.commons.beanutils.NestedNullException;
import org.apache.commons.beanutils.PropertyUtilsBean;

public class ExportUtil<T> {
	
	private StringBuilder csv;
	public static final String EXTENSION_CSV = "CSV";
	private static final Character ASPA = '\"';
	public static final String COMMA = ";";
	public static final String LINEBREAK = "\n";
	private List<String> headersPDF;
	private List<LinePDF> lines;
	private PropertyUtilsBean propertyUtilsBean = new PropertyUtilsBean();
	private String titlePDF;
	
	
	public String exportCSV(Collection<T> genericList, String... attributes) {
		
		this.csv = new StringBuilder();
			
		try {

			// Read List<T> and take values from attributes[]
			for (T genericClass : genericList) {
				for (int i = 0; i < attributes.length; i++) {
					try {
						// Add COMMA
						if (i != 0) {
							this.csv.append(COMMA + ASPA + this.exportValue(genericClass, attributes[i]).replaceAll("\"", "\"\"") + ASPA);
						} else {
							this.csv.append(ASPA + this.exportValue(genericClass, attributes[i]).replaceAll("\"", "\"\"") + ASPA);
						}
					} catch (NestedNullException e) {
						// Add COMMA
						if (i != 0) {
							this.csv.append(COMMA + ASPA + " " + ASPA);
						} else {
							this.csv.append(ASPA + " " + ASPA);
						}
					}
				}
				this.csv.append(LINEBREAK);
			}

		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		
		return csv.toString();
	}
	
	public String exportValue(T genericClass, String attribute) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
		try {
			Object objValue = this.propertyUtilsBean.getProperty(genericClass, attribute);
			return objValue != null ? String.valueOf(objValue) : " ";
		} catch (IllegalAccessException e) {
			throw new IllegalAccessException("Attribute " + attribute + " from class " + genericClass.getClass() + " is not visible!");
		} 

	}
	
	/**
	 * Export PDF
	 * 
	 * @param Collection
	 *            <T>
	 * @param title
	 * @param attributes...
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 * @throws NoSuchMethodException
	 */
	public void exportPDF(Collection<T> genericList, String title, String... attributes) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
		this.setTitlePDF(title);
		this.headersPDF = new LinkedList<String>();
		this.lines = new LinkedList<LinePDF>();

		// Store attributes...
		String[] storedAttributes = new String[attributes.length];
		for (int i = 0; i < storedAttributes.length; i++) {
			String[] attributeHeader = attributes[i].split("-"); // value-header
			storedAttributes[i] = attributeHeader[0]; // value
			this.headersPDF.add(attributeHeader[1]); // header
		}

		for (T genericClass : genericList) {
			LinePDF line = new LinePDF();
			for (int j = 0; j < storedAttributes.length; j++) {
				// Add line values
				try {
					line.addValue(this.exportValue(genericClass, this.propertyUtilsBean.getProperty(genericClass, storedAttributes[j])));
				} catch (IllegalAccessException e) {
					throw new IllegalAccessException("Attribute " + storedAttributes[j] + " from class " + genericClass.getClass() + " is not visible!");
				} catch (InvocationTargetException e) {
					throw new InvocationTargetException(e, e.getMessage());
				} catch (NoSuchMethodException e) {
					line.addValue("");
				} catch (NestedNullException e) {
					line.addValue("");
				}
			}
			this.lines.add(line);
		}
	}


	/**
	 * Return export values
	 * 
	 * @param <T>
	 * @param Object
	 * @return String
	 */
	public String exportValue(T genericClass, Object objValue) {
		return objValue != null ? String.valueOf(objValue) : " ";
	}

	public void setTitlePDF(String titlePDF) {
		this.titlePDF = titlePDF;
	}

	public String getTitlePDF() {
		return titlePDF;
	}
	
	
	
}
